package com.edfeff.nio;

import com.edfeff.bio.http.IAdapter;
import com.edfeff.bio.http.ServerConfig;
import com.edfeff.bio.http.StsException;
import com.edfeff.nio.http.Acceptor;
import com.edfeff.nio.http.Poller;
import com.edfeff.nio.http.SocketOptionsProcessor;
import com.edfeff.nio.http.SocketProcessor;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class ReactorSimpleHttpServer {
    private ServerSocketChannel socketChannel;

    private Executor executor;
    private IAdapter adapter;

    public IAdapter getAdapter() {
        return adapter;
    }

    public ServerSocketChannel getSocketChannel() {
        return socketChannel;
    }

    private final int port;
    private Acceptor acceptor;
    private Poller poller;

    private volatile boolean run = false;

    public ReactorSimpleHttpServer(ServerConfig config) {
        this.port = config.getPort();
        //创建 Adapter
        try {
            Class<? extends IAdapter> adapterClazz = config.getAdapterClass();
            Constructor<? extends IAdapter> declaredConstructor = adapterClazz.getDeclaredConstructor();
            this.adapter = declaredConstructor.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            executor = Executors.newFixedThreadPool(2);

            socketChannel = ServerSocketChannel.open();
            socketChannel.bind(new InetSocketAddress(port));
            socketChannel.configureBlocking(false);

            //单独的线程处理连接事件
            acceptor = new Acceptor(this);
            poller = new Poller(this);

        } catch (IOException e) {
            e.printStackTrace();
            throw new StsException("启动失败");
        }
    }

    public Poller getPoller() {
        return poller;
    }

    public void processSocket(SocketChannel socket) {
        if (run) {
            executor.execute(new SocketOptionsProcessor(this, socket));
        }
    }

    public void processSocketHandler(SocketChannel socket) {
        if (run) {
            executor.execute(new SocketProcessor(this, socket));
        }
    }

    public void start() throws IOException {
        System.out.println("Nio服务器 启动！");
        //启动连接器
        Thread acceptorThread = new Thread(acceptor);
        acceptorThread.setDaemon(true);
        acceptorThread.start();

        //启动poller
        //启动连接器
        Thread pollerThread = new Thread(poller);
        pollerThread.setDaemon(true);
        pollerThread.start();

        run = true;
        await();
    }

    public boolean isRun() {
        return run;
    }

    private void await() {
        while (run) {
            //main
            try {
                Thread.sleep(100000);
            } catch (InterruptedException ex) {
            }
        }
    }

    public void stop() {
        this.run = false;
    }


}
